package aliyun_api

import (
	"errors"
	"fmt"
	"strings"

	"gddgame.cc/galaxy/utils/def"
	"gddgame.cc/galaxy/utils/request"
)

var (
	AuthError  = errors.New("Unauthorized")
	QuotaError = errors.New("Quota Exhausted")
)

type Client struct {
	def.Logger

	agent *request.Pool
}

type AuthInfo struct {
	AppKey    string `json:"appKey"`
	AppSecret string `json:"appSecret"`
	AppCode   string `json:"appCode"`

	Simple bool
}

func NewAuthInfo(appKey string, appSecret string, appCode string) *AuthInfo {
	a := &AuthInfo{
		AppKey:    appKey,
		AppSecret: appSecret,
		AppCode:   appCode,
		Simple:    true,
	}
	return a
}

func NewClient(logger def.Logger) *Client {
	client := &Client{
		Logger: logger,
		agent:  request.NewPool(logger),
	}
	return client
}

func (client *Client) get(authInfo *AuthInfo, url string, data interface{}, result interface{}) error {
	req := client.agent.New().Get(url)
	req.CurlCommand = true
	defer client.agent.Release(req)
	if authInfo.Simple {
		req.AppendHeader("Authorization", "APPCODE "+authInfo.AppCode)
	}
	req.Type("json").Query(data)
	res, _, err := req.EndStruct(result)
	if client.Logger != nil {
		client.Debugf("Aliyun get:%s -> %v", url, err)
	}
	if res.StatusCode == 403 {
		if strings.Contains(res.Status, AuthError.Error()) {
			return AuthError
		} else if strings.Contains(res.Status, QuotaError.Error()) {
			return QuotaError
		}
	}
	if res.StatusCode < 200 || res.StatusCode >= 400 {
		return errors.New(res.Status)
	}
	if err != nil {
		return fmt.Errorf("Aliyun %v", err)
	}
	return nil
}

func (client *Client) post(authInfo *AuthInfo, url string, data interface{}, result interface{}) error {
	req := client.agent.New().Post(url)
	defer client.agent.Release(req)
	if authInfo.Simple {
		req.AppendHeader("Authorization", "APPCODE "+authInfo.AppCode)
	}
	req.Type("json").Send(data)
	res, _, err := req.EndStruct(result)
	client.agent.Release(req)
	if client.Logger != nil {
		client.Debugf("Aliyun get:%s -> %v", url, err)
	}
	if res.StatusCode == 403 {
		if strings.Contains(res.Status, AuthError.Error()) {
			return AuthError
		} else if strings.Contains(res.Status, QuotaError.Error()) {
			return QuotaError
		}
	}
	if res.StatusCode < 200 || res.StatusCode >= 400 {
		return errors.New(res.Status)
	}
	if err != nil {
		return fmt.Errorf("Aliyun %v", err)
	}
	return nil
}
